from reportlab.lib.pagesizes import A4
from reportlab.lib.units import mm
from reportlab.pdfgen import canvas

import math
import os

CAN_WIDTH = A4[0]
CAN_HEIGHT = A4[1]
DRAWABLE_WIDTH = CAN_WIDTH - 20
DRAWABLE_HEIGHT = CAN_HEIGHT - 20

def card_count(card_width:float, card_height:float):
    return int(DRAWABLE_WIDTH / card_width) ,int(DRAWABLE_HEIGHT / card_height)

def card_page(can,cards:list,card_width:float, card_height:float) -> None:
    width_count, height_count = card_count(card_width, card_height)

    for y in range(height_count):
        for x in range(width_count):
            index = x+y*width_count
            if index >= len(cards): break
            card = cards[index]
            pos_x = (CAN_WIDTH - DRAWABLE_WIDTH) /2 + card_width * x
            pos_y = (CAN_HEIGHT - DRAWABLE_HEIGHT) /2 + card_height * y
            can.drawImage(card,pos_x,pos_y,card_width,card_height)
    can.showPage()

def card_page_back(can,cards:list,card_width:float, card_height:float) -> None:
    width_count, height_count = card_count(card_width, card_height)

    for y in range(height_count):
        for x in range(width_count):
            index = x+y*width_count
            if index >= len(cards): break
            card = cards[index]
            pos_x = (CAN_WIDTH + DRAWABLE_WIDTH) /2 - card_width * (x + 1)
            pos_y = (CAN_HEIGHT - DRAWABLE_HEIGHT) /2 + card_height * y
            can.drawImage(card,pos_x,pos_y,card_width,card_height)
    can.showPage()

def split_pages(cards:list, card_width:float, card_height:float):
    x, y = card_count(card_width, card_height)
    count = x*y
    l = len(cards)
    for i in range(math.ceil(l / count)):
        fronts = [card[0] for card in cards[i*count:(i+1)*count]]
        backs = [card[1] for card in cards[i*count:(i+1)*count]]
        yield fronts, backs

def safe_result(base:str):
    os.makedirs(base,exist_ok=True)
    os.makedirs(os.path.join(base,"distribution"),exist_ok=True)

def gen_pdf(base:str,name:str,cards:list,card_width:float, card_height:float):
    safe_result(base)
    fmt = os.path.realpath(os.path.join(base,"distribution","{}.pdf".format(name)))
    can = canvas.Canvas(os.path.realpath(
        os.path.join(fmt)
    ))
    for front, back in split_pages(cards,card_width,card_height):
        card_page(can,front,card_width,card_height)
        card_page_back(can,back,card_width,card_height)
    can.save()

